package com.cui.project.config;


import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;


import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;


@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolConfig implements AsyncConfigurer {

    // ========== 线程池核心参数计算 ==========
    // CPU核心数
    private static final int CPU_NUM = Runtime.getRuntime().availableProcessors();
    
    // IO密集型线程数 = CPU核心数 * 2
    private static final int IO_INTENSIVE_POOL_SIZE = CPU_NUM * 2;
    
    // CPU密集型线程数 = CPU核心数 + 1
    private static final int CPU_INTENSIVE_POOL_SIZE = CPU_NUM + 1;



    /**
     * 1. 默认异步线程池（兜底线程池）
     *
     * 使用场景：
     * - 当 @Async 注解没有指定线程池名称时使用
     * - 兜底保护，避免使用系统默认的 SimpleAsyncTaskExecutor
     * - 适用于轻量级、混合型异步任务
     *
     * 配置说明：
     * - 核心线程：CPU核心数
     * - 最大线程：CPU核心数 * 2
     * - 队列容量：200（适中的缓冲）
     * - 拒绝策略：CallerRunsPolicy（调用者运行，避免任务丢失）
     */
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        int queueCapacity = 200;
        executor.setCorePoolSize(CPU_NUM);
        executor.setMaxPoolSize(CPU_NUM * 2);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("async-default-");
        executor.setKeepAliveSeconds(60);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(30);
        // 允许核心线程超时
        executor.setAllowCoreThreadTimeOut(false);

        executor.initialize();
        log.info("✅ 初始化默认异步线程池: core={}, max={}, queue={}, cpuNum={}",
                executor.getCorePoolSize(), executor.getMaxPoolSize(), 
                queueCapacity, CPU_NUM);
        return executor;
    }

    /**
     * 2. 推荐计算线程池（CPU密集型）
     *
     * 使用场景：
     * - 推荐模型重建（ItemCF、TF-IDF计算）
     * - 数据分析、统计计算
     * - 其他CPU密集型任务
     *
     * 配置说明：
     * - 核心线程 = 最大线程 = CPU核心数 + 1
     * - 队列容量：50（较小队列，避免任务堆积）
     * - 拒绝策略：AbortPolicy（拒绝并抛异常，防止过载）
     * - 说明：CPU密集型任务线程数不宜过多，避免上下文切换开销
     *
     * 使用方式：@Async("recommendExecutor")
     */
    @Bean("recommendExecutor")
    public Executor recommendExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // CPU密集型：线程数 = CPU核心数 + 1
        int queueCapacity = 50;
        executor.setCorePoolSize(CPU_INTENSIVE_POOL_SIZE);
        executor.setMaxPoolSize(CPU_INTENSIVE_POOL_SIZE);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("recommend-");
        executor.setKeepAliveSeconds(120);
        // CPU密集型任务使用AbortPolicy，防止过载
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        executor.setAllowCoreThreadTimeOut(false);

        executor.initialize();
        log.info("✅ 初始化推荐计算线程池(CPU密集): core={}, max={}, queue={}",
                executor.getCorePoolSize(), executor.getMaxPoolSize(), 
                queueCapacity);
        return executor;
    }

    /**
     * 3. IO密集型线程池
     *
     * 使用场景：
     * - 邮件发送（告警通知）
     * - 外部API调用（Python预测服务、第三方接口）
     * - 数据库批量操作
     * - 文件读写操作
     *
     * 配置说明：
     * - 核心线程：CPU核心数 * 2
     * - 最大线程：CPU核心数 * 4
     * - 队列容量：500（较大队列，应对突发流量）
     * - 拒绝策略：CallerRunsPolicy（调用者运行）
     * - 说明：IO密集型任务大部分时间在等待IO，可以开较多线程
     *
     * 使用方式：@Async("ioExecutor")
     */
    @Bean("ioExecutor")
    public Executor ioExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // IO密集型：线程数 = CPU核心数 * 2
        int queueCapacity = 500;
        executor.setCorePoolSize(IO_INTENSIVE_POOL_SIZE);
        executor.setMaxPoolSize(CPU_NUM * 4);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("io-");
        executor.setKeepAliveSeconds(60);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(30);
        executor.setAllowCoreThreadTimeOut(true);

        executor.initialize();
        log.info("✅ 初始化IO密集型线程池: core={}, max={}, queue={}",
                executor.getCorePoolSize(), executor.getMaxPoolSize(), 
                queueCapacity);
        return executor;
    }

    /**
     * 4. 快速响应线程池
     *
     * 使用场景：
     * - 实时通知推送
     * - 缓存预热/刷新
     * - 轻量级异步日志记录
     * - 其他需要快速执行的轻量级任务
     *
     * 配置说明：
     * - 核心线程：CPU核心数
     * - 最大线程：CPU核心数 * 3
     * - 队列容量：100（小队列，快速响应）
     * - 拒绝策略：CallerRunsPolicy
     * - 说明：小队列+多线程，保证快速响应
     *
     * 使用方式：@Async("fastExecutor")
     */
    @Bean("fastExecutor")
    public Executor fastExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        int queueCapacity = 100;
        executor.setCorePoolSize(CPU_NUM);
        executor.setMaxPoolSize(CPU_NUM * 3);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("fast-");
        executor.setKeepAliveSeconds(30);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(20);
        executor.setAllowCoreThreadTimeOut(true);

        executor.initialize();
        log.info("✅ 初始化快速响应线程池: core={}, max={}, queue={}",
                executor.getCorePoolSize(), executor.getMaxPoolSize(), 
                queueCapacity);
        return executor;
    }


    /**
     * 全局异步任务异常处理器
     *
     * 功能：
     * - 捕获所有异步任务中未被捕获的异常
     * - 记录详细的错误日志（方法名、参数、异常堆栈）
     * - 避免异常被静默吞掉导致问题难以排查
     *
     * 注意：
     * - 此处理器适用于所有线程池的异步任务
     * - 建议在业务代码中也做好异常处理，此处作为最后的保护网
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) -> {
            log.error("╔════════════════════════════════════════════════════════════════╗");
            log.error("║            ⚠️  异步任务执行失败  ⚠️                           ║");
            log.error("╠════════════════════════════════════════════════════════════════╣");
            log.error("║ 方法名    : {}", method.getName());
            log.error("║ 所属类    : {}", method.getDeclaringClass().getName());
            log.error("║ 参数个数  : {}", params.length);
            if (params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                    log.error("║ 参数[{}]   : {}", i, params[i]);
                }
            }
            log.error("║ 异常类型  : {}", ex.getClass().getName());
            log.error("║ 异常信息  : {}", ex.getMessage());
            log.error("╠════════════════════════════════════════════════════════════════╣");
            log.error("║ 异常堆栈  :");
            log.error("╚════════════════════════════════════════════════════════════════╝", ex);
        };
    }
}
